package com.panda.sports.manager.query;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.panda.sports.manager.constant.Constant;
import com.panda.sports.manager.entity.StandardMatchInfo;
import com.panda.sports.manager.entity.ThirdMatchInfo;
import com.panda.sports.manager.enums.MatchOddsType;
import com.panda.sports.manager.utils.TimeUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author :  dorich
 * @project Name :  panda_data_service
 * @package Name :  com.panda.sports.manager.query
 * @description :   查询比赛的条件 vo
 * @date: 2019-08-07 13:09
 * @ModificationHistory Who    When    What
 * --------  ---------  --------------------------
 */
@Data
@Slf4j
@ApiModel(description = "比赛查询条件")
public class MatchQuery {
    public static List<String> DATA_SOURCE_LIST = new ArrayList<>();

    static {
        DATA_SOURCE_LIST.add(Constant.DATA_SOURCE_SR);
        DATA_SOURCE_LIST.add(Constant.DATA_SOURCE_BC);
    }

    /**
     * 是否仅查询标准赛事的默认值
     */
    public static Integer DEFAULT_VALUE_ONLY_QUERY = 1;
    /**
     * 数据库中int  和  long 的默认值
     **/
    public static Integer DEFAULT_VALUE_INT = 0;

    /**
     * 每页数据个数
     **/
    @ApiModelProperty(name = "每页数据量，默认50")
    private Integer size = 50;

    /**
     * 从第几页开始
     **/
    @ApiModelProperty(name = "从第几页开始，默认1")
    private Integer page = 1;

    @ApiModelProperty(name = "标准赛事的id", notes = "标准赛事的id")
    private Long id;

    @ApiModelProperty(name = "是否仅查询标准赛事", notes = "1:仅查询标准赛事")
    private Integer onlyStandard;


    @ApiModelProperty(name = "赛事状态")
    private Long matchStatus;

    @ApiModelProperty(name = "比赛开始时间下限参数", notes = "时间戳精确到秒，UTC时间")
    private Long startTimeFrom;

    @ApiModelProperty(name = "比赛开始时间上限参数", notes = "时间戳精确到秒，UTC时间")
    private Long startTimeEnd;

    @ApiModelProperty(name = "联赛级别")
    private Integer leagueLevel;

    /**
     * 数据来源编码。
     **/
    @ApiModelProperty(name = "联赛数据来源编码列表", notes = "联赛数据来源编码列表. SR BC MA:已匹配；UMA:未匹配；其余值: 全部")
    private List<String> dataSourceCode;

    @ApiModelProperty(name = "盘口状态-数据供应商")
    private String oddStatusFirst;

    @ApiModelProperty(name = "盘口状态-开盘状态",notes = "0：未开盘；1：开盘；2：关盘；3：封盘；开盘后用户可下注")
    private Integer oddStatusSecond;


    /**
     * 确认 list中是否仅包含一种数据源编码
     * @description
     * @param   list   数据源编码列表
     * @param  contain 被检测的数据源编码
     * @author  dorich
     * @date   2019/8/14
     * @return boolean
     **/
    private static boolean whetherOnlyContain(List<String> list, String contain) {
        if(list.contains(Constant.DATA_SOURCE_BC) && list.contains(Constant.DATA_SOURCE_SR)) {
            return false;
        }
        return list.contains(contain);
    }

    /**
     * 根据查询条件，生成标准赛事的 wrapper
     *
     * @param query 查询条件vo
     * @return com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<StandardMatchInfo>
     * @description 生成标准赛事 的查询 wrapper
     * @author dorich
     * @date 2019/8/9
     **/
    public static UpdateWrapper getStandardWrapper(MatchQuery query) {

        UpdateWrapper<StandardMatchInfo> wrapper = new UpdateWrapper<>();
        // 增加体育种类限制，暂时仅查询足球
        wrapper.lambda().eq(StandardMatchInfo::getSportId, Constant.SPORT_TYPE_FOOTBALL);

        // 前端希望仅使用1个id 查询 指定标准联赛的数据
        if(null != query.getId() && query.getId() > 0) {
            wrapper.lambda().eq(StandardMatchInfo::getId, query.getId());
        }

        // 比赛数据源
        if (null != query.getDataSourceCode()) {
            List<String> dataSourceCodeList = query.getDataSourceCode();
            if (whetherOnlyContain(dataSourceCodeList, Constant.DATA_SOURCE_BC)) {
                wrapper.lambda().eq(StandardMatchInfo::getDataSourceCode, Constant.DATA_SOURCE_BC);
            } else if (whetherOnlyContain(dataSourceCodeList,Constant.DATA_SOURCE_SR)) {
                wrapper.lambda().eq(StandardMatchInfo::getDataSourceCode, Constant.DATA_SOURCE_SR);
            }
        }

        // 联赛级别
        if (null != query.getLeagueLevel() && query.getLeagueLevel() >= 0 && query.getLeagueLevel() <= Constant.MAX_LEVEL) {
            wrapper.lambda().eq(StandardMatchInfo::getTournamentLevel, query.getLeagueLevel());
        }

        // 赛事状态。必须符合要求
        if (null != query.getMatchStatus()) {
            wrapper.lambda().eq(StandardMatchInfo::getMatchPeriodId, query.getMatchStatus());
        }

        // 比赛开始时间地区分布；
        // 数据库 中存放的比赛开始时间时UTC时间，而产品需求是 UTC-4时间，因此需要时间转换
        if (null != query.getStartTimeFrom()) {
            wrapper.lambda().gt(StandardMatchInfo::getBeginTime, TimeUtils.timeMillsSecondsToPlus4TimeZone(query.getStartTimeFrom()));
        }
        if (null != query.getStartTimeEnd()) {
            wrapper.lambda().lt(StandardMatchInfo::getBeginTime, TimeUtils.timeMillsSecondsToPlus4TimeZone(query.getStartTimeEnd()));
        }

        // 盘口状态
        if (null != query.getOddStatusFirst()) {
            // 该分支处理 panda开盘，panda封盘   SR开盘，SR封盘 BC开盘，BC封盘
            if (null != query.getOddStatusSecond()) {
                // oddStatusFirst 字段的含义是 风控 服务器上
                wrapper.lambda().eq(StandardMatchInfo::getRiskManagerCode, query.getOddStatusFirst());
                // 比赛的开盘状态
                wrapper.lambda().eq(StandardMatchInfo::getOperateMatchStatus, query.getOddStatusSecond());
            }
        } else if (null != query.getOddStatusSecond()) {
            // 该分支处理 未开盘 无盘口数据
            wrapper.lambda().eq(StandardMatchInfo::getOperateMatchStatus, MatchOddsType.UNODDS.getValue());
        }

        // 后增加的比赛肯定是最需要处理的，因此放在最前边
        wrapper.lambda().orderByDesc(StandardMatchInfo::getId);

        return wrapper;
    }

    /**
     * 根据查询条件生成 第三方赛事的查询wrapper
     *
     * @param queryPara 查询条件
     * @return com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<ThirdMatchInfo>
     * @description 生成第三方赛事的查询wrapper
     * @author dorich
     * @date 2019/8/9
     **/
    public static UpdateWrapper getThirdWrapper(MatchQuery queryPara) {

        if(null != queryPara.getId() && queryPara.getId() > 0) {
            return null;
        }
        //如果仅查询标准赛事，则不查询 第三方赛事
        if (null != queryPara.getOnlyStandard() && queryPara.getOnlyStandard().intValue() == DEFAULT_VALUE_ONLY_QUERY) {
            return null;
        }

        // 第三方赛事没有联赛级别，因此一旦传入这个参数在，则不查询
        if (null != queryPara.getLeagueLevel()) {
            return null;
        }
        // 比赛状态 第三方赛事没有该参数，因此一旦传入这个参数在，则不查询
        if (null != queryPara.getMatchStatus()) {
            return null;
        }
        // 盘口状态 第三方赛事没有该参数，因此一旦传入这个参数在，则不查询
        if (null != queryPara.getOddStatusFirst() || null != queryPara.getOddStatusSecond()) {
            return null;
        }

        UpdateWrapper<ThirdMatchInfo> wrapper = new UpdateWrapper<>();
        // 此查询条件中仅查询 未关联数据，关联的数据根据表联赛条件进行查询。
        wrapper.lambda().eq(ThirdMatchInfo::getReferenceId, MatchQuery.DEFAULT_VALUE_INT);
        // 限定数据来源只能是SR BC 不能是其他
        wrapper.lambda().in(ThirdMatchInfo::getDataSourceCode, MatchQuery.DATA_SOURCE_LIST);
        // 限定体育种类是足球，TODO 如果支持其他体育种类，需要在此修改
        wrapper.lambda().eq(ThirdMatchInfo::getSportId, Constant.SPORT_TYPE_FOOTBALL);
        // 比赛开始时间地区分布；
        // 数据库 中存放的比赛开始时间时UTC时间，而产品需求是 UTC-4时间，因此需要时间转换
        if (null != queryPara.getStartTimeFrom()) {
            wrapper.lambda().gt(ThirdMatchInfo::getBeginTime, TimeUtils.timeMillsSecondsToPlus4TimeZone(queryPara.getStartTimeFrom()));
        }
        if (null != queryPara.getStartTimeEnd()) {
            wrapper.lambda().lt(ThirdMatchInfo::getBeginTime, TimeUtils.timeMillsSecondsToPlus4TimeZone(queryPara.getStartTimeEnd()));
        }

        // 赛事 数据源。
        if (null != queryPara.getDataSourceCode()) {
            if (queryPara.getDataSourceCode().contains(Constant.DATA_SOURCE_MA)) {
                // 已匹配的数据由 标准联赛查询后根据其他条件查询
                return null;
            }
            if (queryPara.getDataSourceCode().contains(Constant.DATA_SOURCE_UM)) {
                wrapper.lambda().eq(ThirdMatchInfo::getReferenceId, TournamentQuery.DEFAULT_VALUE_INT);
            }
            // 如果查询参数中限定了 数据来源种类，则必须制定 数据的来源
            List<String> dataSourceCodeList = queryPara.getDataSourceCode();
            if(whetherOnlyContain(dataSourceCodeList,Constant.DATA_SOURCE_BC)) {
                wrapper.lambda().eq(ThirdMatchInfo::getDataSourceCode, Constant.DATA_SOURCE_BC);
            } else if (whetherOnlyContain(dataSourceCodeList,Constant.DATA_SOURCE_SR)) {
                wrapper.lambda().eq(ThirdMatchInfo::getDataSourceCode, Constant.DATA_SOURCE_SR);
            }
        }
        return wrapper;
    }


    public static UpdateWrapper getWrapper(Class<?> clas, MatchQuery query) {
        if (clas.equals(StandardMatchInfo.class)) {
            log.info(clas.getName());
            return getStandardWrapper(query);
        }
        if (clas.equals(ThirdMatchInfo.class)) {
            log.info(clas.getName());
            return getThirdWrapper(query);
        }
        return null;
    }

}